package com.example.dayu521.gateway.conf;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.same.SaSameUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.example.dayu521.gateway.filter.AddLoginIdFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;

/**
 * [Sa-Token 权限认证] 配置类
 * @author click33
 */
@Configuration
public class SaTokenConfigure {
    // 注册 Sa-Token全局过滤器
    @Bean
    public SaReactorFilter getSaReactorFilter() {
//        return new AddLoginIdFilter()
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")    /* 拦截全部path */
                // 开放地址
                .addExclude("/favicon.ico","/pay/pay_listen/alipay")
                // 鉴权方法：每次访问进入
                .setAuth(obj -> {
                    //todo 根据数据库的url动态校验
                    // 登录校验 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
                    SaRouter.match("/**", "/f1/user/doLogin", r -> {
                        StpUtil.checkLogin();
                        //把login_id存到context中,然后在其他过滤器中获取它,并设置到下游request的header
                        // 这里就在当前继承类中完成
                        // https://gitee.com/dromara/sa-token/issues/I73M3L
                        ServerWebExchange context = SaReactorSyncHolder.getContext();
                        context.getAttributes().put(AddLoginIdFilter.Tpx,StpUtil.getLoginIdAsString());
                    });

                    // 权限认证 -- 不同模块, 校验不同权限
                    SaRouter.match("/sg-oss/oss/listobj", r -> {
                        StpUtil.checkRole("admin");
                        StpUtil.checkPermission("sg-oss:list");
                    });

                    // 更多匹配 ...  */
                })
                // 异常处理方法：每次setAuth函数出现异常时进入
                .setError(e -> {
                    if(e instanceof NotLoginException nle)
                        return SaResult.error(nle.getMessage()).setCode(11010);
                    return SaResult.error(e.getMessage());
                })
                ;
    }
}

